﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using deckAnalyser.Support;
using deckAnalyser.Forms;
using ZedGraph;
using deckAnalyser.Domain;
using deckAnalyser.Controls;
using System.Net;
using System.IO;
using System.Threading;

namespace deckAnalyser
{

  public partial class MainForm : Form
  {
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(MainForm));


    private void Init()
    {
      String appName = "DeckAnalyser";
      String appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), appName);
      String appDocPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), appName);

#if DEBUG
      Text = Text + " (Debug)";
      appDataPath = "..\\..\\..\\data\\";
      appDocPath = "..\\..\\..\\data\\";
#else
#endif
      if (!Directory.Exists(appDataPath)) Directory.CreateDirectory(appDataPath);
      if (!Directory.Exists(Path.Combine(appDataPath, "images"))) Directory.CreateDirectory(Path.Combine(appDataPath, "images"));
      if (!Directory.Exists(appDocPath)) Directory.CreateDirectory(appDocPath);

      DBWrapper.Open(appDataPath, "deckAnalyser.s3db");
      DBWrapper.Attach(appDataPath, "mtgt_master.s3db", "master");
      DBWrapper.Attach(appDocPath, "collections.s3db", "collections");

      ImageCache.Open(Path.Combine(appDataPath, "images"));

      DBWrapper.ExecuteNonQuery(
        "CREATE TABLE IF NOT EXISTS collections.collectioncards (" +
        "name text  NOT NULL," +
        "cardname text  NOT NULL," +
        "setname text  NOT NULL," +
        "cnt integer," +
        "fcnt integer," +
        "UNIQUE (name,cardname,setname)" +
        ")"
      );

      DBWrapper.ExecuteNonQuery(
        "CREATE TABLE IF NOT EXISTS collections.collections (" +
        "name text  NOT NULL," +
        "description text  NULL," +
        "UNIQUE (name)" +
        ")"
      );

      DBWrapper.ExecuteNonQuery(
        "CREATE TABLE IF NOT EXISTS settings (" +
        "name text NOT NULL," +
        "value text NOT NULL," +
        "UNIQUE (name)" +
        ")"
      );
    }

    public MainForm()
    {
      log.Debug("Creating the main form");
      splashForm.Show();
      Init();

      InitializeComponent();


      AllowDrop = true;

      DragEnter += new DragEventHandler(MainForm_DragEnter);
      DragDrop += new DragEventHandler(MainForm_DragDrop);
    }

    SplashForm splashForm = new SplashForm();
    DeckInfoForm deckInfoForm = new DeckInfoForm();
    OptionsForm optionsForm = new OptionsForm();

    private DomainObject currentDommainObject
    {
      get
      {
        if (tabControl_main.SelectedTab != null)
          return tabControl_main.SelectedTab.Tag as DomainObject;
        else return null;
      }
    }


    ToolStripMenuItem tsmiFile;
    ToolStripMenuItem tsmiFileNew;
    ToolStripMenuItem tsmiNewDeck;
    ToolStripMenuItem tsmiNewCollection;
    ToolStripMenuItem tsmiFileOpen;
    ToolStripMenuItem tsmiOpenDeck;
    ToolStripMenuItem tsmiOpenCollection;
    ToolStripMenuItem tsmiFileClose;
    ToolStripMenuItem tsmiFileSave;
    ToolStripMenuItem tsmiFileSaveAs;
    ToolStripMenuItem tsmiFileSaveAll;
    ToolStripMenuItem tsmiFileExit;

    ToolStripMenuItem tsmiTools;
    ToolStripMenuItem tsmiToolsOptions;

    private void MainForm_Load(object sender, EventArgs e)
    {
      // The File Menu
      //
      tsmiFile = new ToolStripMenuItem("&File");
      tsmiFileNew = new ToolStripMenuItem("&New", default(Image));
      tsmiNewDeck = new ToolStripMenuItem("&Deck", imageList.Images["filenew.png"], (f, x) => createDeck());
      tsmiNewCollection = new ToolStripMenuItem("&Collection", imageList.Images["filenew.png"], (f, x) => createCollection());

      tsmiFileOpen = new ToolStripMenuItem("&Open", default(Image));
      tsmiOpenDeck = new ToolStripMenuItem("&Deck", imageList.Images["fileopen.png"], (f, x) => openDeck());
      tsmiOpenCollection = new ToolStripMenuItem("&Collection", imageList.Images["fileopen.png"], (f, x) => openCollection());

      tsmiFileClose = new ToolStripMenuItem("&Close", imageList.Images["fileclose.png"], (f, x) => close());
      tsmiFileSave = new ToolStripMenuItem("&Save", imageList.Images["filesave.png"], (f, x) => save());
      tsmiFileSaveAs = new ToolStripMenuItem("Save &As...", imageList.Images["filesaveas.png"], (f, x) => saveAs());
      tsmiFileSaveAll = new ToolStripMenuItem("Save A&ll", imageList.Images["save_all.png"], (f, x) => saveAs());
      tsmiFileExit = new ToolStripMenuItem("E&xit", imageList.Images["exit.png"], (f, x) => Close());


      // The Tools Menu
      //
      tsmiTools = new ToolStripMenuItem("Tools");
      tsmiToolsOptions = new ToolStripMenuItem("Options...", imageList.Images["utilities.png"], (f, x) => optionsForm.ShowDialog(this));


      menuStrip.Items.Add(tsmiFile);
      tsmiFile.DropDown.Items.Add(tsmiFileNew);
      tsmiFileNew.DropDown.Items.Add(tsmiNewDeck);
      tsmiFileNew.DropDown.Items.Add(tsmiNewCollection);
      tsmiFile.DropDown.Items.Add(tsmiFileOpen);
      tsmiFileOpen.DropDown.Items.Add(tsmiOpenDeck);
      tsmiFileOpen.DropDown.Items.Add(tsmiOpenCollection);
      tsmiFile.DropDown.Items.Add(new ToolStripSeparator());
      tsmiFile.DropDown.Items.Add(tsmiFileClose);
      tsmiFile.DropDown.Items.Add(new ToolStripSeparator());
      tsmiFile.DropDown.Items.Add(tsmiFileSave);
      tsmiFile.DropDown.Items.Add(tsmiFileSaveAs);
      tsmiFile.DropDown.Items.Add(tsmiFileSaveAll);
      tsmiFile.DropDown.Items.Add(new ToolStripSeparator());
      tsmiFile.DropDown.Items.Add(tsmiFileExit);


      menuStrip.Items.Add(tsmiTools);
      tsmiTools.DropDown.Items.Add(tsmiToolsOptions);

      foreach (String fileName in Options.GetAll("OpenDecks"))
        if (!String.IsNullOrEmpty(fileName))
          openDeck(new Deck(fileName));

      foreach (String name in Options.GetAll("OpenCollections"))
        if (!String.IsNullOrEmpty(name))
          openCollection(new Collection(name));

    }

    void tabControl_main_MouseClick(object sender, MouseEventArgs e)
    {
      //RectangleF tabTextArea = (RectangleF)this.GetTabRect(SelectedIndex);
      //tabTextArea =
      //    new RectangleF(tabTextArea.X + tabTextArea.Width - 16, 5, 13, 13);
      //Point pt = new Point(e.X, e.Y);
      //if (tabTextArea.Contains(pt))


      //if (e.Button == MouseButtons.Right)
      //{

      //}
    }

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
      e.Cancel = saveUnsavedWork();

      if (!e.Cancel)
      {
        Options.Remove("OpenDecks");
        Options.Remove("OpenCollections");

        foreach (TabPage page in tabControl_main.TabPages)
        {
          if (page.Tag is Deck)
          {
            Deck deck = page.Tag as Deck;
            Options.Set("OpenDecks", deck.FileName);
          }
          else if (page.Tag is Collection)
          {
            Collection collection = page.Tag as Collection;
            Options.Set("OpenCollections", collection.Name);
          }
        }

        Options.Save();
      }
    }

    private bool saveUnsavedWork()
    {
      List<Deck> decksRequiredSaving = new List<Deck>();
      foreach (TabPage page in tabControl_main.TabPages)
        if (page.Tag is Deck)
        {
          Deck deck = page.Tag as Deck;
          if (deck.IsDirty)
            decksRequiredSaving.Add(deck);
        }

      if (decksRequiredSaving.Count > 0)
      {
        DialogResult result = MessageBox.Show("Save unsaved work?", "Unsaved work", MessageBoxButtons.YesNoCancel);

        if (result == DialogResult.Yes)
        {
          foreach (Deck deck in decksRequiredSaving)
          {
            if (String.IsNullOrEmpty(deck.FileName))
            {
              DialogResult result2 = saveFileDialog.ShowDialog(this);

              if (result2 == DialogResult.OK)
              {
                deck.FileName = saveFileDialog.FileName;
                deck.Save();
              }
            }
            else
              deck.Save();
          }
        }

        if (result == DialogResult.Cancel)
          return true;
      }

      return false;
    }

    private void close()
    {
      TabPage selectedTab = tabControl_main.SelectedTab;

      if (selectedTab == null) return;

      if (selectedTab.Tag is Deck)
      {
        Deck deck = selectedTab.Tag as Deck;
        if (saveUnsavedWork())
          return;

        tabControl_main.TabPages.Remove(selectedTab);
      }

      if (selectedTab.Tag is Collection)
      {
        Collection collection = selectedTab.Tag as Collection;

        tabControl_main.TabPages.Remove(selectedTab);
      }
    }

    private void closeCollection(Collection collection)
    {
    }

    private void save()
    {
      TabPage selectedTab = tabControl_main.SelectedTab;

      if (selectedTab == null) return;

      if (selectedTab.Tag is Deck)
      {
        Deck deck = selectedTab.Tag as Deck;

        if (String.IsNullOrEmpty(deck.FileName))
        {
          saveFileDialog.FileName = deck.Name + ".dec";
          DialogResult result = saveFileDialog.ShowDialog(this);

          if (result == DialogResult.OK)
          {
            deck.FileName = saveFileDialog.FileName;
            deck.Save();
          }
        }
        else
          deck.Save();
      }

    }

    private void saveAs()
    {
      TabPage selectedTab = tabControl_main.SelectedTab;

      if (selectedTab == null) return;

      if (selectedTab.Tag is Deck)
      {
        if (selectedTab.Tag is Deck)
        {
          Deck deck = selectedTab.Tag as Deck;

          saveFileDialog.FileName = deck.FileName;
          DialogResult result = saveFileDialog.ShowDialog(this);

          if (result == DialogResult.OK)
          {
            deck.FileName = saveFileDialog.FileName;
            deck.Save();
          }
        }
      }
    }

    private void createCollection()
    {

    }



    private void createDeck()
    {
      deckInfoForm.DeckName = "";
      deckInfoForm.Author = Options.Get("DefaultAuthor", "");
      deckInfoForm.Notes = "";

      DialogResult result = deckInfoForm.ShowDialog(this);

      if (result == DialogResult.OK)
        openDeck(new Deck(deckInfoForm.DeckName, deckInfoForm.Author, deckInfoForm.Notes));
    }

    private void openDeck()
    {
      DialogResult result = openFileDialog.ShowDialog(this);

      if (result == DialogResult.OK)
        openDeck(new Deck(openFileDialog.FileName));
    }

    private void openDeck(Deck deck)
    {
      DeckBuilderControl dbc = new DeckBuilderControl();
      dbc.Deck = deck;
      dbc.Dock = DockStyle.Fill;

      TabPage page = new TabPage(deck.Caption);
      page.Controls.Add(dbc);
      page.Tag = deck;

      tabControl_main.TabPages.Add(page);
      tabControl_main.SelectedTab = page;


      deck.OnUpdate += (d) => page.Text = d.Caption;
    }

    private void saveDeck()
    {
      TabPage selectedTab = tabControl_main.SelectedTab;

      if (selectedTab != null)
      {
        if (selectedTab.Tag is Deck)
        {

        }
      }
    }

    private void saveDeckAs()
    {
      TabPage selectedTab = tabControl_main.SelectedTab;

      if (selectedTab != null)
      {
      }
    }

    private void saveAll()
    {
    }

    private void editDeckInformation()
    {
      TabPage selectedTab = tabControl_main.SelectedTab;

      if (selectedTab != null)
      {
        if (selectedTab.Tag is Deck)
        {
          Deck deck = selectedTab.Tag as Deck;


          deckInfoForm.DeckName = deck.Name;
          deckInfoForm.Author = deck.Author;
          deckInfoForm.Notes = deck.Notes;

          DialogResult result = deckInfoForm.ShowDialog(this);

          if (result == DialogResult.OK)
          {
            deck.Name = deckInfoForm.DeckName;
            deck.Author = deckInfoForm.Author;
            deck.Notes = deckInfoForm.Notes;
          }
        }
      }
    }

    public void openCollection()
    {
      Collection collection = new Collection(Options.Get("DefaultCollection", "Default"));
      openCollection(collection);
    }

    public void openCollection(Collection collection)
    {
      CollectionManagerControl cmc = new CollectionManagerControl();
      cmc.CollectionName = collection.Name;
      cmc.Dock = DockStyle.Fill;

      TabPage page = new TabPage(collection.Caption);
      page.Controls.Add(cmc);
      page.Tag = collection;

      tabControl_main.TabPages.Add(page);
      tabControl_main.SelectedTab = page;
    }

    private void MainForm_DragDrop(object sender, DragEventArgs e)
    {
      this.Text = ((String)e.Data.GetData(typeof(String))).Split('\n')[0];

      WebClient wc = new WebClient();
      byte[] data = wc.DownloadData(this.Text);
      openDeck(new Deck(data));
    }

    private void MainForm_DragEnter(object sender, DragEventArgs e)
    {
      e.Effect = DragDropEffects.Copy;
    }

    private void MainForm_Activated(object sender, EventArgs e)
    {
      splashForm.Close();
    }

  }
}
